package top.ninwoo.utils.util.impl;

import org.springframework.beans.factory.annotation.Autowired;
import top.ninwoo.utils.util.DockerUtils;
import top.ninwoo.utils.util.TcUtils;
import top.ninwoo.utils.util.Utils;

import java.io.*;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author joliu
 * @Description
 * @Date　Create in 下午5:20 2019/10/30
 */
@Utils
public class TcUtilsImpl implements TcUtils {

    @Autowired
    DockerUtils dockerUtils;

    Set<String> supportPolicies = new HashSet<>();

    {
        supportPolicies.add("distribution");
    }



    /**
     * latency
     * @param containerId
     * @param maxRate 1mbit
     * @param latency 500ms 超过这个阈值的将被直接丢弃
     * @return
     */
    @Override
    public boolean addQos(String containerId, String maxRate, String latency) {
        String res = dockerUtils.execInDocker(containerId, "tc qdisc add dev eth1 root tbf rate " + maxRate + " burst 32kbit latency " + latency);
        //dockerUtils.execInDocker("limit 10k burst 10k mtu 5000")
        if(!"".equals(res)) {
            return false;
        }
        return true;
    }


    /**
     * 解除限速
     * @param containerId
     * @return
     */
    @Override
    public boolean delQos(String containerId) {
        String res = dockerUtils.execInDocker(containerId, "tc qdisc del dev eth1 root");
        if(!"".equals(res)) {
            return false;
        }
        return true;
    }

    @Override
    public boolean addDelay(String containerId, String mode, int delay) {
        return addDelay(containerId, mode, delay, 0, 0);
    }

    @Override
    public boolean addDelay(String containerId, String mode, int delay, int randomDelay) {
        return addDelay(containerId, mode, delay, randomDelay, 0);
    }

    /**
     * 添加时延
     * @param containerId
     * @param delay 添加的延迟
     * @param randomDelay 随机时延范围
     * @param correlation 相关系数
     * @return
     */
    @Override
    public boolean addDelay(String containerId, String mode, int delay, int randomDelay, int correlation) {
        return addDelay(containerId, mode, delay, randomDelay, correlation, 0);
    }

    @Override
    public boolean addDelay(String containerId, String mode, int delay, int randomDelay, int correlation, int loss) {
        // tc qdisc add dev eth1 root netem loss 10%
        String cmd = "tc qdisc " + mode + " dev eth1 root netem ";
        if(delay > 0) {
            cmd += delay + "ms ";
        }
        if(randomDelay > 0) {
            cmd += randomDelay + "ms ";
        }
        if(correlation >0 && correlation < 100) {
            cmd += correlation + "% ";
        }
        if(loss > 0) {
            cmd += "loss " + loss + "%";
        }
        String res = dockerUtils.execInDocker(containerId, cmd);
        if("".equals(res)) {
            return true;
        }
        return false;
    }
    /**
     * 正太分布的随机延时
     * @param contianerId
     * @param delay
     * @param randomDelay
     * @param policy distribution是目前支持的
     * @return
     */
    @Override
    public boolean addDelay(String contianerId, String mode, int delay, int randomDelay, String policy) {


        if(!supportPolicies.contains(policy)) {
            return false;
        }
        String cmd = "tc qdisc " + mode + " dev eth1 netem delay " + delay + "ms " + randomDelay + "ms " + policy + " normal";
        String res = dockerUtils.execInDocker(contianerId, cmd);
        if("".equals(res)) {
            return true;
        }
        return false;
    }
}
